﻿using System;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Threading;
using _3DTicTacToe.Core;

namespace _3DTicTacToe
{
    sealed class NameTextBox : TextBox
    {
        public NameTextBox()
        {
            TextChanged += NameTextBox_TextChanged;
            NameTextBox_TextChanged(null, null);
        }

        public delegate void IsValidNameChangedDlg(bool valid);
        public delegate void LastValidNameDlg(string name);

        public event IsValidNameChangedDlg IsValidNameChanged;
        public event LastValidNameDlg LastValidNameChanged;

        private bool _isValidName;
        public bool IsValidName
        {
            get { return _isValidName; }
            set 
            {
                if (value != _isValidName && IsValidNameChanged != null)
                {
                    _isValidName = value; 
                    IsValidNameChanged(value);
                    return;
                }
                _isValidName = value; 
            }
        }

        private string _lastValidName;
        public string LastValidName
        {
            get { return _lastValidName; }
            private set
            {
                _lastValidName = value;
                if (LastValidNameChanged != null)
                    LastValidNameChanged(value);
            }
        }

        #region validation

        string GetText()
        {
            return Text;
        }

        void SetInvalid()
        {
            var colorAnimation = new ColorAnimation
                            {
                                From = (IsValidName)?Colors.White:Colors.Tomato,
                                To = Colors.Tomato,
                                Duration = new Duration(TimeSpan.FromMilliseconds(200))
                            };

            var storyboard = new Storyboard();
            storyboard.Children.Add(colorAnimation);
            Storyboard.SetTargetName(colorAnimation, Name);
            Storyboard.SetTargetProperty(colorAnimation, new PropertyPath("Background.Color"));

            storyboard.Begin(this);
            IsValidName = false;
        }

        void SetValid()
        {
            LastValidName = Text;

            var colorAnimation = new ColorAnimation
            {
                From = (IsValidName) ? Colors.White : Colors.Tomato,
                To = Colors.White,
                Duration = new Duration(TimeSpan.FromMilliseconds(200))
            };

            var storyboard = new Storyboard();
            storyboard.Children.Add(colorAnimation);
            Storyboard.SetTargetName(colorAnimation, Name);
            Storyboard.SetTargetProperty(colorAnimation, new PropertyPath("Background.Color"));

            storyboard.Begin(this);
            IsValidName = true;
        }

        void ValidateText(object state)
        {
            var text = Dispatcher.Invoke(DispatcherPriority.Normal, new Func<string>(GetText)) as string;
            var valid = Player.IsValidName(text);

            if (valid)
                Dispatcher.Invoke(new Action(SetValid));
            else
                Dispatcher.Invoke(new Action(SetInvalid));
        }

        void NameTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            ThreadPool.QueueUserWorkItem(ValidateText);
        }

        #endregion
    }
}
